home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 102_01.zip / FISH.C < prev    next >
Text File  |  1993-06-03  |  10KB  |  499 lines

  1. /*
  2.     "Go Fish"
  3.  
  4.     Modified for BDS C by Leor Zolman    2/82
  5. */
  6.  
  7. #include <bdscio.h>
  8. #define stderr 4
  9.  
  10. /*    Through, `my' refers to the program, `your' to the player */
  11.  
  12. #define CTYPE 13
  13. #define CTSIZ (CTYPE+1)
  14. #define DECK 52
  15. #define NOMORE 0
  16. #define DOUBTIT (-1);
  17.  
  18. /* data structures */
  19.  
  20. int debug;
  21.  
  22. char myhand[CTSIZ];
  23. char yourhand[CTSIZ];
  24. char deck[DECK];
  25. int nextcd;
  26. int proflag;
  27.  
  28. /* utility and output programs */
  29.  
  30. shuffle(){
  31.     /* shuffle the deck, and reset nextcd */
  32.     /* uses the random number generator `rand' in the C library */
  33.     /* assumes that `srand' has already been called */
  34.  
  35.     register i,j;
  36.  
  37.     for( i=0; i<DECK; ++i ) deck[i] = (i%13)+1;  /* seed the deck */
  38.  
  39.     for( i=DECK; i>0; --i ){ /* select the next card at random */
  40.         deck[i-1] = choose( deck, i );
  41.         }
  42.  
  43.     nextcd = 0;
  44.     }
  45.  
  46. choose( a, n ) char a[]; {
  47.     /* pick and return one at random from the n choices in a */
  48.     /* The last one is moved to replace the one chosen */
  49.     register j, t;
  50.  
  51.     if( n <= 0 ) error( "null choice" );
  52.  
  53.     j = rand() % n;
  54.     t = a[j];
  55.     a[j] = a[n-1];
  56.     return(t);
  57.     }
  58.  
  59. draw() {
  60.     if( nextcd >= DECK ) return( NOMORE );
  61.     return( deck[nextcd++] );
  62.     }
  63.  
  64. error( s ) char *s; {
  65.     fprintf( stderr, "error: " );
  66.     fprintf( stderr, s );
  67.     exit( 1 );
  68.     }
  69.  
  70. empty( h ) char  h[CTSIZ]; {
  71.     register i;
  72.  
  73.     for( i=1; i<=CTYPE; ++i ){
  74.         if( h[i] != 0 && h[i] != 4 ) return( 0 );
  75.         }
  76.     return( i );
  77.     }
  78.  
  79. mark( hand,cd ) char hand[CTSIZ]; {
  80.     if( cd != NOMORE ){
  81.         ++hand[cd];
  82.         if( hand[cd] > 4 ){
  83.             error( "mark overflow" );
  84.             }
  85.         }
  86.     return( cd );
  87.     }
  88.  
  89. deal( hand, n ) char hand[CTSIZ]; {
  90.     while( n-- ){
  91.         if( mark( hand, draw() ) == NOMORE ) error( "deck exhausted" );
  92.         }
  93.     }
  94.  
  95. char *cname[14];
  96.  
  97. stats(){
  98.     register i, ct, b;
  99.  
  100.     if( proflag ) printf( "Pro level\n" );
  101.     b = ct = 0;
  102.  
  103.     for( i=1; i<=CTYPE; ++i ){
  104.         if( myhand[i] == 4 ) ++b;
  105.         else ct += myhand[i];
  106.         }
  107.  
  108.     if( b ){
  109.         printf( "My books: " );
  110.         for( i=1; i<=CTYPE; ++i ){
  111.             if( myhand[i] == 4 ) printf( "%s ", cname[i] );
  112.             }
  113.         printf( "\n" );
  114.         }
  115.  
  116.     printf( "%d cards in my hand, %d in the pool\n", ct, DECK-nextcd );
  117.     printf( "You ask me for: " );
  118.     }
  119.  
  120. phand( h ) char h[CTSIZ]; {
  121.     register i, j;
  122.  
  123.     j = 0;
  124.  
  125.     for( i = 1; i<= CTYPE; ++i ){
  126.         if( h[i] == 4 ) {
  127.             ++j;
  128.             continue;
  129.             }
  130.         if( h[i] ){
  131.             register k;
  132.             k = h[i];
  133.             while( k-- ) printf( "%s ", cname[i] );
  134.             }
  135.         }
  136.  
  137.     if( j ){
  138.         printf( "+ Books of " );
  139.         for( i=1; i<=CTYPE; ++i ){
  140.             if( h[i] == 4 ) printf( "%s ", cname[i] );
  141.             }
  142.         }
  143.  
  144.     printf( "\n" );
  145.     }
  146.  
  147. main( argc, argv ) char * argv[]; { 
  148.     /* initialize shuffling, ask for instructions, play game, die */
  149.     register c;
  150.  
  151.     cname[0] = "NOMORE!!!";
  152.     cname[1] = "A";
  153.     cname[2] = "2";
  154.     cname[3] = "3";
  155.     cname[4] = "4";
  156.     cname[5] = "5";
  157.     cname[6] = "6";
  158.     cname[7] = "7";
  159.     cname[8] = "8";
  160.     cname[9] = "9";
  161.     cname[10] = "10";
  162.     cname[11] = "J";
  163.     cname[12] = "Q";
  164.     cname[13] = "K";
  165.  
  166.     if( argc > 1 && argv[1][0] == '-') debug++;
  167.  
  168.  
  169.     srand1("Instructions? ");
  170.  
  171.     if( (c=tolower(getchar())) != 'n' )
  172.         instruct();
  173.     putchar('\n');
  174.     game();
  175.     }
  176.  
  177. /*    print instructions */
  178.  
  179. instruct(){
  180. printf("\n`Go Fish' is a children's card game. The object is to accumulate\n");
  181. printf("`books' of 4 cards with the same face value. Players alternate\n");
  182. printf("turns; each turn begins with one player selecting a card from his\n");
  183. printf("hand, and asking the other player for all cards of that value.\n");
  184. printf("If the other player has one or more cards of that face value\n");
  185. printf("in his hand, he gives them to the first player, and the first\n");
  186. printf(" player makes another request.\n");
  187. printf("Eventually, the first player asks for a card which is not in the\n");
  188. printf("second player's hand: he replies `GO FISH!'\n");
  189. printf("The first player then draws a card from the pool of undealt cards.\n");
  190. printf("If this is the card he had last requested, he draws again.\n");
  191. printf("When a book is made, either through drawing or requesting, the\n");
  192. printf("cards are laid down and no further action takes place with that\n");
  193. printf("face value.\n");
  194. printf("To play the computer, simply make guesses by typing\n");
  195. printf("a, 2, 3, 4, 5, 6, 7, 8, 9, 10, j, q, or k when asked.\n");
  196. printf("Hitting return gives you information about the size of\n");
  197. printf("my hand and the pool, and tells you about my books.\n");
  198. printf("Saying `p' as a first guess puts you into `pro' level;\n");
  199. printf("The default is pretty dumb!   G O O D   L U C K!\n");
  200. }
  201.  
  202. /* play game */
  203.  
  204. game(){
  205.     int i,j;
  206.     shuffle();
  207.  
  208.     for (i = 0; i < CTSIZ; i++) {
  209.         myhand[i] = 0;
  210.         yourhand[i] = 0;
  211.     }
  212.         
  213.     deal( myhand, 7 );
  214.     deal( yourhand, 7 );
  215.  
  216.     start( myhand );
  217.  
  218.     for(;;){
  219.  
  220.         register g;
  221.  
  222.  
  223.         /* you make repeated guesses */
  224.  
  225.         for(;;) {
  226.             printf( "your hand is: " );
  227.             phand( yourhand );
  228.             printf( "you ask me for: " );
  229.             if( !move( yourhand, myhand, g=guess(), 0 ) ) break;
  230.             printf( "Guess again\n" );
  231.             }
  232.  
  233.         /* I make repeated guesses */
  234.  
  235.         for(;;) {
  236.             if( (g=myguess()) != NOMORE ){
  237.                 printf( "I ask you for: %s\n", cname[g] );
  238.                 }
  239.             if( !move( myhand, yourhand, g, 1 ) ) break;
  240.             printf( "I get another guess\n" );
  241.             }
  242.         }
  243.     }
  244.  
  245. /*    reflect the effect of a move on the hands */
  246.  
  247. move( hs, ht, g, v ) char hs[CTSIZ], ht[CTSIZ]; {
  248.     /* hand hs has made a guess, g, directed towards ht */
  249.     /* v on indicates that the guess was made by the machine */
  250.     register d;
  251.     char *sp, *tp;
  252.  
  253.     sp = tp = "I";
  254.     if( v ) tp = "You";
  255.     else sp = "You";
  256.  
  257.     if( g == NOMORE ){
  258.         d = draw();
  259.         if( d == NOMORE ) score();
  260.         else {
  261.  
  262.             printf( "Empty Hand\n" );
  263.             if( !v ) printf( "You draw %s\n", cname[d] );
  264.             mark( hs, d );
  265.             }
  266.         return( 0 );
  267.         }
  268.  
  269.     if( !v ) heguessed( g );
  270.  
  271.     if( hs[g] == 0 ){
  272.         if( v ) error( "Rotten Guess" );
  273.         printf( "You don't have any %s's\n", cname[g] );
  274.         return(1);
  275.         }
  276.  
  277.     if( ht[g] ){ /* successful guess */
  278.  
  279.         printf("%s have ",tp);
  280.         switch(ht[g]) {
  281.             case 1: printf("one "); break;
  282.             case 2:    printf("two "); break;
  283.             case 3: printf("three "); break;
  284.             case 4: printf("four "); break;
  285.         }
  286.         printf("%s%s\n",cname[g], ht[g] > 1 ? "'s" : "");
  287.  
  288.         hs[g] += ht[g];
  289.         ht[g] = 0;
  290.         if( hs[g] == 4 ) madebook(g);
  291.         return(1);
  292.         }
  293.  
  294.     /* GO FISH! */
  295.  
  296.     printf( "%s say \"GO FISH!\"\n", tp );
  297.  
  298.     newdraw:
  299.     d = draw();
  300.     if( d == NOMORE ) {
  301.         printf( "No more cards\n" );
  302.         return(0);
  303.         }
  304.     mark( hs, d );
  305.     if( !v ) printf( "You draw %s\n", cname[d] );
  306.     if( hs[d] == 4 ) madebook(d);
  307.     if( d == g ){
  308.         printf( "%s drew the guess, so draw again\n", sp );
  309.         if( !v ) hedrew( d );
  310.         goto newdraw;
  311.         }
  312.     return( 0 );
  313.     }
  314.  
  315. madebook( x ){
  316.     printf( "Made a book of %s's\n", cname[x] );
  317.     }
  318.  
  319. score(){
  320.     register my, your, i;
  321.  
  322.     my = your = 0;
  323.  
  324.     printf( "The game is over.\nMy books: " );
  325.  
  326.     for( i=1; i<=CTYPE;++i ){
  327.         if( myhand[i] == 4 ){
  328.             ++my;
  329.             printf( "%s ", cname[i] );
  330.             }
  331.         }
  332.  
  333.     printf( "\nYour books: " );
  334.  
  335.     for( i=1; i<=CTYPE;++i ){
  336.         if( yourhand[i] == 4 ){
  337.             ++your;
  338.             printf( "%s ", cname[i] );
  339.             }
  340.         }
  341.  
  342.     printf( "\n\nI have %d, you have %d\n", my, your );
  343.  
  344.     printf( "\n%s win!!!\n", my>your?"I":"You" );
  345.     exit(0);
  346.     }
  347.  
  348. #define G(x) { if(go) goto err;  else go = x; }
  349.  
  350. guess(){
  351.     /* get the guess from the tty and return it... */
  352.     register g, go;
  353.  
  354.     go = 0;
  355.  
  356.     for(;;) {
  357.         switch( g = getchar() ){
  358.  
  359.         case 'p':
  360.         case 'P':
  361.             ++proflag;
  362.             continue;
  363.  
  364.         case '2':
  365.         case '3':
  366.         case '4':
  367.         case '5':
  368.         case '6':
  369.         case '7':
  370.         case '8':
  371.         case '9':
  372.             G(g-'0');
  373.             continue;
  374.  
  375.         case 'a':
  376.         case 'A':
  377.             G(1);
  378.             continue;
  379.  
  380.         case '1':
  381.             G(10);
  382.             continue;
  383.  
  384.         case '0':
  385.             if( go != 10 ) goto err;
  386.             continue;
  387.  
  388.         case 'J':
  389.         case 'j':
  390.             G(11);
  391.             continue;
  392.  
  393.         case 'Q':
  394.         case 'q':
  395.             G(12);
  396.             continue;
  397.  
  398.         case 'K':
  399.         case 'k':
  400.             G(13);
  401.             continue;
  402.  
  403.         case '\n':
  404.             if( empty( yourhand ) ) return( NOMORE );
  405.             if( go == 0 ){
  406.                 stats();
  407.                 continue;
  408.                 }
  409.             return( go );
  410.  
  411.         case ' ':
  412.         case '\t':
  413.             continue;
  414.  
  415.         err:
  416.         default:
  417.             while( g != '\n' ) g = getchar();
  418.             printf( "what?\n" );
  419.             continue;
  420.             }
  421.         }
  422.     }
  423.  
  424. /*    the program's strategy appears from here to the end */
  425.  
  426. char try[100];
  427. char ntry;
  428. char haveguessed[CTSIZ];
  429.  
  430. char hehas[CTSIZ];
  431.  
  432. start( h ) char h[CTSIZ]; {
  433.     ;
  434.     }
  435.  
  436. hedrew( d ){
  437.     ++hehas[d];
  438.     }
  439.  
  440. heguessed( d ){
  441.     ++hehas[d];
  442.     }
  443.  
  444. myguess(){
  445.  
  446.     register i, lg, t;
  447.  
  448.     if( empty( myhand ) ) return( NOMORE );
  449.  
  450.     /* make a list of those things which i have */
  451.     /* leave off any which are books */
  452.     /* if something is found that he has, guess it! */
  453.  
  454.     ntry = 0;
  455.     for( i=1; i<=CTYPE; ++i ){
  456.         if( myhand[i] == 0 || myhand[i] == 4 ) continue;
  457.         try[ntry++] = i;
  458.         }
  459.  
  460.     if( !proflag ) goto random;
  461.  
  462.     /* get ones he has, if any */
  463.  
  464.     for( i=0; i<ntry; ++i ){
  465.         if( hehas[try[i]] ) {
  466.             i = try[i];
  467.             goto gotguess;
  468.             }
  469.         }
  470.  
  471.     /* is there one that has never been guessed; if so, guess it */
  472.     lg = 101;
  473.     for( i=0; i<ntry; ++i ){
  474.         if( haveguessed[try[i]] < lg ) lg = haveguessed[try[i]];
  475.         }
  476.     /* remove all those not guessed longest ago */
  477.  
  478.     t = 0;
  479.     for( i=0; i<ntry; ++i ){
  480.         if( haveguessed[try[i]] == lg ) try[t++] = try[i];
  481.         }
  482.     ntry = t;
  483.     if( t <= 0 ) error( "bad guessing loop" );
  484.  
  485.     random:
  486.     i = choose( try, ntry );  /* make a random choice */
  487.  
  488.     gotguess:  /* do bookkeeping */
  489.  
  490.     hehas[i] = 0;  /* he won't anymore! */
  491.     for( t=1; t<=CTYPE; ++t ){
  492.         if( haveguessed[t] ) --haveguessed[t];
  493.         }
  494.     haveguessed[i] = 100;  /* will have guessed it */
  495.     return(i);
  496.  
  497.     }
  498.  
  499.